#include "qtc_alarm_core/AlarmTree.h"
#include "qtc_alarm_core/AlarmEvent.h"

using namespace qtc_alarm_core;

QJsonObject AlarmTreeNode::toJson() const {
    QJsonObject obj;
    obj["name"] = name;
    obj["severity"] = severity;
    obj["pv_count"] = pv_count;
    QJsonArray arr;
    for (const auto& key : children.keys()) {
        arr.append(children[key]->toJson());
    }
    if (!arr.isEmpty()) obj["children"] = arr;
    return obj;
}

AlarmTree::AlarmTree(const QString& root_name) {
    root = QSharedPointer<AlarmTreeNode>::create(root_name);
}

QString AlarmTree::worstSeverity(const QString& a, const QString& b) {
    // Severity ordering: MAJOR > MINOR > OK > UNKNOWN
    auto rank = [](const QString& s) {
        const QString u = s.toUpper();
        if (u == "MAJOR") return 3;
        if (u == "MINOR") return 2;
        if (u == "OK") return 1;
        return 0;
    };
    return rank(a) >= rank(b) ? a : b;
}

QSharedPointer<AlarmTreeNode> AlarmTree::ensurePath(const QStringList& parts) {
    auto node = root;
    for (const auto& p : parts) {
        if (!node->children.contains(p)) {
            node->children[p] = QSharedPointer<AlarmTreeNode>::create(p);
        }
        node = node->children[p];
    }
    return node;
}

void AlarmTree::applyEvent(const AlarmEvent& ev) {
    // Split PV name into segments. Accept ':' or '/' as separators
    QString pvpath = ev.pv;
    pvpath.replace('/', ':');
    const QStringList parts = pvpath.split(":", Qt::SkipEmptyParts);
    if (parts.isEmpty()) return;
    auto leaf = ensurePath(parts);
    leaf->pv_count += 1; // count appearances in demo
    leaf->severity = worstSeverity(leaf->severity, ev.severity);
    // Bubble up worst severity to ancestors
    // Re-walk path to update parents
    auto node = root;
    for (const auto& p : parts) {
        node->severity = worstSeverity(node->severity, ev.severity);
        node = node->children[p];
    }
}

QJsonObject AlarmTree::toJson() const {
    return root->toJson();
}